const obj = {
    name: 'Anzia',
    age: 22,
    gender: '男'
};

const arr = [['name', 'Anzia'], ['age', 22], ['gender', '男']];

// entries
// 将对象转成键值对数组
Object.prototype.sx_entries = function (obj) {
    const res = [];
    for (let key in obj) {
        // hasOwnProperty() 回传对象是否有该属性的boolean值
        obj.hasOwnProperty(key) && res.push([key, obj[key]])
    }
    return res;
}
console.log(Object.sx_entries(obj));
// [ [ 'name', 'Anzia' ], [ 'age', 22 ], [ 'gender', '男' ] ]

// fromEntries
// 跟entries相反，将键值对数组转成对象
Object.prototype.sx_fromEntries = function (arr) {
    const obj = {}
    for (let i = 0; i < arr.length; i++) {
        const [key, value] = arr[i] // 解构赋值
        obj[key] = value;
    }
    return obj;
}
console.log(Object.sx_fromEntries(arr));
// { name: 'Anzia', age: 22, gender: '男' }

// keys
// 将对象的key转成一个数组合集
Object.prototype.sx_keys = function (obj) {
    const res = [];
    for (let key in obj) {
        obj.hasOwnProperty(key) && res.push(key);
    }
    return res;
}
console.log(Object.sx_keys(obj));
// [ 'name', 'age', 'gender' ]

// values
// 将对象的所有值转成数组合集
Object.prototype.sx_values = function (obj) {
    const res = [];
    for (let key in obj) {
        obj.hasOwnProperty(key) && res.push(obj[key]);
    }
    return res;
}
console.log(Object.sx_values(obj));
// [ 'Anzia', 22, '男' ]

// instanceOf
// A instanceOf B，判断A是否经过B的原型链
function sx_instanceOf(father, child) {
    const fp = father.prototype;
    var cp = child.__proto__;

    while (cp) {
        if (cp == fp) {
            return true;
        }
        cp = cp.__proto__;
    }

    return false;
}

function Person(name) {
    this.name = name;
}
const sx = new Person('Anzia')

console.log(sx_instanceOf(Person, sx)); // true
// 每个实例对象（ object ）都有一个私有属性（称之为 __proto__ ）指向它的构造函数的原型对象（ prototype ）
// 该原型对象也有一个自己的原型对象( __proto__ ) ，层层向上直到一个对象的原型对象为 null
// 根据定义，null 没有原型，并作为这个原型链中的最后一个环节
// 几乎所有 JavaScript 中的对象都是位于原型链顶端的 Object 的实例

// is
// Object.is(a, b)，判断a是否等于b
Object.prototype.sx_is = function (x, y) {
    if (x === y) {
        // 防止 -0 和 +0
        return x !== 0 || 1 / x === 1 / y;
    }
    // 防止 NaN
    return x !== x && y !== y;
}
const a = {name: 'Anzia'};
const b = a;
const c = {name: 'Anzia'};
console.log(Object.sx_is(a, b)); // true
console.log(Object.sx_is(a, c)); // false

// assign
// 接收多个对象，并将多个对象合成一个对象
Object.prototype.sx_assign = function (target, ...args) {
    if (target === null || target === undefined) {
        throw new TypeError('Cannot convert undefined or null to object');
    }
    target = Object(target);

    for (let nextObj of args) {
        for (let key in nextObj) {
            nextObj.hasOwnProperty(key) && (target[key] = nextObj[key]);
        }
    }

    return target;
}

const testa = {name: 'Anzia'};
const testb = {name: 'HarmonyOS', age: 3};
const testc = {age: 18, gender: '男'};

const testd = Object.sx_assign(testa, testb, testc)
console.log(testd); // { name: 'HarmonyOS', age: 18, gender: '男' }
console.log(testa === testd); // true